package com.cndw.kongfu.messagepush;

import java.io.IOException;
import java.io.InputStream;
import java.net.InetSocketAddress;
import java.net.Socket;
import java.util.HashMap;
import java.util.Map;
import java.util.concurrent.Executors;

import org.jboss.netty.bootstrap.ClientBootstrap;
import org.jboss.netty.buffer.ChannelBuffer;
import org.jboss.netty.buffer.ChannelBufferInputStream;
import org.jboss.netty.buffer.ChannelBuffers;
import org.jboss.netty.channel.Channel;
import org.jboss.netty.channel.ChannelFuture;
import org.jboss.netty.channel.socket.nio.NioClientSocketChannelFactory;

import com.cndw.kongfu.net.MySocketRequest;
import com.cndw.kongfu.util.Aes;
import com.cndw.kongfu.util.MD5;
import com.cndw.kongfu.util.TimeProcesser;
import com.cndw.rpg.framework.ResponseMessage;
import com.cndw.rpg.framework.codec.Compress;

import flex.messaging.io.SerializationContext;
import flex.messaging.io.amf.Amf3Input;

public class SendTest {
	public static SerializationContext context;
	
	private static String loginKey = "tencent-login-8159a693-ebd7-4ec6-8e1d-4384bd6551aa";
	private static String partnerEName = "localhost";
//	private static String partnerEName = "tencent";
	private static String pf = "qzone";
	private static String loginExt = "1,0,openkey,pfkey,0,0,0";
//	private static String loginExt = "1,1,9F0EC056C08DBCF6A7FC1333A20F4B2A,2cbb2847166c567d43a31d956250314b,0,0,0,0";
	
//	private static String openId = "F33E27800D1B02B3C96D1475FF4B5D5A";
	private static String openId = "ch03";
	static {
		context = new SerializationContext();
		context.legacyCollection = true;
	}
	
	public static ChannelFuture future ;
	public static ClientBootstrap bootstrap;

	/**
	 * @param args
	 */
	public static void main(String[] args) {
		// TODO Auto-generated method stub
//		send();
		sendMsg();
	}

	public static ResponseMessage send() {
		int time = TimeProcesser.getUnixTime();
		Map<String, Object> map = new HashMap<String, Object>();
		map.put("openId", openId);
		map.put("time", time + "");
		map.put("pf", pf);
		String sign = MD5.compile(partnerEName+","+openId+ "," + time +"," + pf +","+ loginExt+"," + loginKey);
		map.put("sign", sign);
		map.put("ext", loginExt);
		ResponseMessage message = null;
		try {
			Socket socket = new Socket();
//			socket.connect(new InetSocketAddress("s10.app100622837.qqopenapp.com", 8001), 2000);
			socket.connect(new InetSocketAddress("localhost", 7782), 2000);
			socket.setSoTimeout(15000);
			socket.setTcpNoDelay(true);
			socket.setKeepAlive(true);
			MySocketRequest loginRequest = new MySocketRequest("LoginController", "auth", map);
			socket.getOutputStream().write(loginRequest.serialize().array());
			socket.getOutputStream().flush();
			Amf3Input input = new Amf3Input(context);
			InputStream stream = null;
			ChannelBuffer buffer = ChannelBuffers.dynamicBuffer();
			int bodySize = 0;
			int compressSize = 0;
			byte bytes[] = new byte[1024];
			ChannelBuffer bodyBuffer = null;
			while (true) {
				bodySize = 0;
				compressSize = 0;
				stream = socket.getInputStream();
				do {
					int length = stream.read(bytes);
					if (length != -1)
						buffer.writeBytes(bytes, 0, length);
					while (bodySize == 0 && buffer.readableBytes() >= 4) {
						bodySize = buffer.readInt();
						if (bodySize > 1024 && compressSize == 0) {
							compressSize = bodySize;
							bodySize = 0;
						}
					}
				} while (buffer.readableBytes() < bodySize);
				
				if (compressSize > 0) {
					byte cpomressBytes[] = Compress.decompressBytes(buffer.readBytes(bodySize).array());
					bodyBuffer = buffer.factory().getBuffer(cpomressBytes.length);
					bodyBuffer.writeBytes(cpomressBytes);
				} else {
					bodyBuffer = buffer.factory().getBuffer(bodySize);
					bodyBuffer.writeBytes(buffer, bodySize);
				}
				input.setInputStream(new ChannelBufferInputStream(bodyBuffer));
				message = (ResponseMessage) input.readObject();
				bodyBuffer.clear();
				System.out.println(message.m);
				input.close();
//				if (socket != null)
//					socket.close();
//				return message;
			}
			
		} catch (IOException e) {
			e.printStackTrace();
		} catch (ClassNotFoundException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		} finally {
			
		}
		return message;
	}
	
	public static void sendMsg() {
		bootstrap = new ClientBootstrap(new NioClientSocketChannelFactory(Executors.newCachedThreadPool(), Executors.newCachedThreadPool()));
		bootstrap.setPipelineFactory(new MyChannelPipelineFactory());
		bootstrap.setOption("tcpNoDelay" , true);   
        bootstrap.setOption("keepAlive", true); 
		future = bootstrap.connect(new InetSocketAddress("localhost", 7782));
		Channel channel = future.awaitUninterruptibly().getChannel();
		if (!future.isSuccess()) {
			future.getCause().printStackTrace();
			bootstrap.releaseExternalResources();
			return;
		}
		MySocketRequest loginRequest = new MySocketRequest("LoginController", "auth", getLoginMap());
		future = channel.write(loginRequest.serialize());
//		if (future.isSuccess())
//			System.exit(0);
		future.awaitUninterruptibly();
//		bootstrap.releaseExternalResources();
//		KeepAlive.runBoss();
	}
	
	public static void sendIdleMessage () {
		Channel channel = future.awaitUninterruptibly().getChannel();
		if (!future.isSuccess()) {
			future.getCause().printStackTrace();
			bootstrap.releaseExternalResources();
			return;
		}
		MySocketRequest loginRequest = new MySocketRequest("LoginController", "idleMessage");
		future = channel.write(loginRequest.serialize());
	}

	public static String getCipher(String... params) {
		StringBuilder param = new StringBuilder();
		for (String p : params) {
			param.append(p);
			param.append("\r\n");
		}
		param.append(TimeProcesser.getUnixTime());
		return Aes.encrypt(param.toString());
	}
	
	public static Map<String, Object> getLoginMap() {
		int time = TimeProcesser.getUnixTime();
		Map<String, Object> map = new HashMap<String, Object>();
		map.put("openId", openId);
		map.put("time", time + "");
		map.put("pf", pf);
		String sign = MD5.compile(partnerEName+","+openId+ "," + time +"," + pf +","+ loginExt+"," + loginKey);
		map.put("sign", sign);
		map.put("ext", loginExt);
		return map;
	}
	
	public static void sendXX(ChannelBuffer buffer) {
		Channel channel = future.awaitUninterruptibly().getChannel();
		if (!future.isSuccess()) {
			future.getCause().printStackTrace();
			bootstrap.releaseExternalResources();
			return;
		}
		future = channel.write(MySocketRequest.sendXX());
//		if (future.isSuccess())
//			System.exit(0);
		future.awaitUninterruptibly();
	}
	
	// protected static final String openId = "openId";
			// protected static final String time = "time";
			// protected static final String pf = "pf";
			// protected static final String userName = "userName";
			// protected static final String ext = "ext";
			// protected static final String openKey = "openKey";
			// protected static final String pfKey = "pfKey";
			// protected static final String al = "al";
			// protected static final String yYear = "yYear";
			// protected static final String yLevel = "yLevel";
			// protected static final String sign = "sign";
			// protected static final String type = "type";

}


